﻿// dlg_device_scan.cpp: 实现文件
//

#include "pch.h"
#include "CamCtrl.h"
#include "afxdialogex.h"
#include "dlg_device_scan.h"
#include "dlg_main.h"
#include <vector>

#pragma comment(lib,"Iphlpapi.lib")


IMPLEMENT_DYNAMIC(dlg_device_scan, CDialogEx)

dlg_device_scan::dlg_device_scan(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_DLG_DEVICE_SCAN, pParent)
{
    scan = nullptr;
    ctrl = nullptr;
    cfg  = nullptr;
}

dlg_device_scan::~dlg_device_scan()
{
    if(scan) delete scan;
    if(ctrl) delete ctrl;
	if(cfg)  delete cfg;
    scan = nullptr;
	ctrl = nullptr;
    cfg  = nullptr;
}

void dlg_device_scan::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(dlg_device_scan, CDialogEx)
    ON_CBN_SELCHANGE(IDC_COMBO_LOCAL_NETCARD, &dlg_device_scan::OnCbnSelchangeComboLocalNetcard)
    ON_BN_CLICKED(IDC_BTN_START_SCAN_DEVICE, &dlg_device_scan::OnBnClickedBtnStartScanDevice)
    ON_MESSAGE(MSG_DEVICE_INFO,        &dlg_device_scan::OnNewDeviceInfo)
    ON_MESSAGE(MSG_DEVICE_CTRL,        &dlg_device_scan::OnNewDeviceCfgMsg)
    ON_BN_CLICKED(IDC_BTN_OPEN_DEVICE, &dlg_device_scan::OnBnClickedBtnOpenDevice)
END_MESSAGE_MAP()


/*来自于主对话框的配置消息*/
// 这里的逻辑在处理dlg_main里面的按钮
// messagesand都send到这里来了
/*来自于device_ctrl的设备上线消息*/
LRESULT dlg_device_scan::OnNewDeviceCfgMsg(WPARAM wParam, LPARAM lParam)
{
    struct device_info* info = (struct device_info*)wParam;
    int cmd = *(int*)lParam;

    switch (cmd)
    {
        case CMD_DEVICE_CTRL:        ctrl->ctrl(info);          break;  /*设备控制消息*/
        case CMD_DEVICE_REFRESH:     ctrl->refresh();           break;  /*设备刷新消息*/
        case CMD_DEVICE_REBOOT:      ctrl->reboot();            break;  /*设备重启消息*/
        case CMD_DEVICE_CLOSE:       ShowWindow(SW_SHOWNORMAL); break;  /*设备关闭消息*/
        /*设备刷新消息，直接转到*/
        case CMD_DEVICE_REFRESH_ACK: if(cfg) ::SendMessage(cfg->GetSafeHwnd(), MSG_DEVICE_CTRL, wParam, lParam); break;
        default: break;
    }
    return 0;
}

/*来自于设备的设备信息消息*/
LRESULT dlg_device_scan::OnNewDeviceInfo(WPARAM wParam, LPARAM lParam)
{
    int count = *(int*)wParam;
    u8 *ip = (u8*)lParam;

    if (count == 0)
    {
        ((CComboBox*)GetDlgItem(IDC_COMBO_DEVICE_IP))->ResetContent();
        ((CComboBox*)GetDlgItem(IDC_COMBO_DEVICE_NAME))->ResetContent();
    }

    char *name = (char*)(ip+4);

    ((CComboBox*)GetDlgItem(IDC_COMBO_DEVICE_NAME ))->InsertString(count, name);
    ((CComboBox*)GetDlgItem(IDC_COMBO_DEVICE_NAME))->SetCurSel(count);
    GetDlgItem(IDC_COMBO_DEVICE_NAME)->EnableWindow(TRUE);
    GetDlgItem(IDC_BTN_OPEN_DEVICE)->EnableWindow(TRUE);
    
    string ip_addr_trans(u8 ip[4]);
    string ip_str = ip_addr_trans(ip);
    ((CComboBox*)GetDlgItem(IDC_COMBO_DEVICE_IP))->InsertString(count, ip_str.c_str());
    ((CComboBox*)GetDlgItem(IDC_COMBO_DEVICE_IP))->SetCurSel(count);
    GetDlgItem(IDC_COMBO_DEVICE_IP)->EnableWindow(FALSE);
    return 0;
}

BOOL dlg_device_scan::OnInitDialog()
{
    /*struct device_info info;
    init_file_decode("example.ini", &info);*/

	CDialogEx::OnInitDialog();

    ((CComboBox*)GetDlgItem(IDC_COMBO_DEVICE_IP))->InsertString(0, "不可用");
    ((CComboBox*)GetDlgItem(IDC_COMBO_DEVICE_NAME))->InsertString(0, "不可用");
    ((CComboBox*)GetDlgItem(IDC_COMBO_DEVICE_IP))->SetCurSel(0);
    ((CComboBox*)GetDlgItem(IDC_COMBO_DEVICE_NAME))->SetCurSel(0);
    GetDlgItem(IDC_COMBO_DEVICE_IP)->EnableWindow(FALSE);
    GetDlgItem(IDC_COMBO_DEVICE_NAME)->EnableWindow(FALSE);

    // https://blog.csdn.net/qq_29022265/article/details/120954136

    PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO();
    unsigned long stSize = sizeof(IP_ADAPTER_INFO);
    int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);
    int netCardNum = 0;

    int IPnumPerNetCard = 0;

    int active_id = 0;

    if (ERROR_BUFFER_OVERFLOW == nRel)
    {
        delete pIpAdapterInfo;
        pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[stSize];
        nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);
    }
    if (ERROR_SUCCESS == nRel)
    {
        while (pIpAdapterInfo)
        {
            ((CComboBox*)GetDlgItem(IDC_COMBO_LOCAL_NETCARD))->InsertString(netCardNum, pIpAdapterInfo->Description);

            IP_ADDR_STRING* pIpAddrString = &(pIpAdapterInfo->IpAddressList);
            int IPnumPerNetCard = 0;
            do
            {
                ((CComboBox*)GetDlgItem(IDC_COMBO_LOCAL_IP))->InsertString(netCardNum, pIpAddrString->IpAddress.String);
                CString ip = pIpAddrString->IpAddress.String;
                if (ip != "0.0.0.0")
                {
                    active_id = netCardNum;
                }
                pIpAddrString = pIpAddrString->Next;
            } while (pIpAddrString);
            pIpAdapterInfo = pIpAdapterInfo->Next;
            netCardNum++;
        }
    }
    if (pIpAdapterInfo)
    {
        delete []pIpAdapterInfo;
    }

    ((CComboBox*)GetDlgItem(IDC_COMBO_LOCAL_NETCARD))->SetCurSel(active_id);
    ((CComboBox*)GetDlgItem(IDC_COMBO_LOCAL_IP))->SetCurSel(active_id);

    GetDlgItem(IDC_BTN_OPEN_DEVICE)->EnableWindow(FALSE);

	return TRUE;  
}


void dlg_device_scan::OnCbnSelchangeComboLocalNetcard()
{
   int id = ((CComboBox*)GetDlgItem(IDC_COMBO_LOCAL_NETCARD))->GetCurSel();
   ((CComboBox*)GetDlgItem(IDC_COMBO_LOCAL_IP))->SetCurSel(id);
}


void dlg_device_scan::OnBnClickedBtnStartScanDevice()
{
    CString ip_addr;
    GetDlgItem(IDC_COMBO_LOCAL_IP)->GetWindowText(ip_addr);

    if (scan == nullptr)
    {
        scan = new device_scan(_T(""),ip_addr.GetBuffer());
    }
    else
    {
    }
    
    ((CComboBox*)GetDlgItem(IDC_COMBO_DEVICE_IP))->ResetContent();
    ((CComboBox*)GetDlgItem(IDC_COMBO_DEVICE_IP))->InsertString(0, _T("不可用"));
    ((CComboBox*)GetDlgItem(IDC_COMBO_DEVICE_IP))->SetCurSel(0);
    GetDlgItem(IDC_COMBO_DEVICE_IP)->EnableWindow(FALSE);

    ((CComboBox*)GetDlgItem(IDC_COMBO_DEVICE_NAME))->ResetContent();
    ((CComboBox*)GetDlgItem(IDC_COMBO_DEVICE_NAME))->InsertString(0, _T("不可用"));
    ((CComboBox*)GetDlgItem(IDC_COMBO_DEVICE_NAME))->SetCurSel(0);  
    GetDlgItem(IDC_COMBO_DEVICE_NAME)->EnableWindow(FALSE);
    GetDlgItem(IDC_BTN_OPEN_DEVICE)->EnableWindow(FALSE);


    scan->notify_win = this->GetSafeHwnd();
    scan->my_ip_addr = ip_addr.GetBuffer();//这里又赋了一遍值, 可能是需要更换网卡?
    scan->scan();
}


void dlg_device_scan::OnBnClickedBtnOpenDevice()
{
    CString ip_addr;

    if (ctrl != nullptr)
    {
        delete ctrl;
    }
    
    ctrl = new device_ctrl();
    ctrl->notify_win = this->GetSafeHwnd();
    
    /*尝试连接设备端服务器*/
    GetDlgItem(IDC_COMBO_DEVICE_IP)->GetWindowText(ip_addr);
    if (ctrl->run(ip_addr.GetBuffer()) > 0)
    {
		/*隐藏本对话框并启动配置界面*/
		ShowWindow(SW_HIDE);
		if (cfg == nullptr)
		{
			cfg = new dlg_main();// 这里新建了一个配置页面
			cfg->Create(IDD_MAIN_DLG, this);
			cfg->notify_wnd = this->GetSafeHwnd();//把scan窗口的句柄传给配置页面
		}
		cfg->ShowWindow(SW_SHOW);
        /*启动时刷新一次设备信息*/
        cfg->OnBnClickedBtnRefresh();// 这里就是在给linux端发送一个cmd了
    }
}

